import { isPrimitive, isPlainObj, deepCopy, isDef } from '@/utils/index'
import request from '@/utils/axios'
import { plainFilterAttr, replaceValue, handleObject } from './util'
import { ElMessage } from 'element-plus'

export function handleApi(api, instance, extra) {
  let requestConfig, successMsg, showErrorMsg, errorMsg, responseData
  if (isPrimitive(api)) {
    requestConfig = {
      url: replaceValue(api, instance)
    }
  } else if (isPlainObj(api)) {
    successMsg = api.successMsg
    showErrorMsg = api.showErrorMsg
    errorMsg = api.errorMsg
    requestConfig = plainFilterAttr(deepCopy(api), [
      'requestAdaptor',
      'responseAdaptor',
      'initDataFields',
      'showSuccessMsg',
      'successMsg',
      'showErrorMsg',
      'errorMsg'
    ])
    requestConfig.url = replaceValue(requestConfig.url, instance)
    requestConfig.data = handleObject(requestConfig.data || {}, instance)
  }
  if (!requestConfig) {
    return false
  } else {
    if (extra) {
      requestConfig.data = {
        ...extra,
        ...requestConfig.data
      }
    }
  }
  responseData = requestConfig.responseData
  if (!isDef(responseData)) {
    responseData = 'data'
  }

  if (isPlainObj(api) && api.requestAdaptor) {
    requestConfig = api.requestAdaptor(requestConfig)
  }
  return request(requestConfig)
    .then((res) => {
      if (isDef(successMsg)) {
        ElMessage.success(successMsg || res.msg)
      }
      if (isPlainObj(api)) {
        if (api.responseAdaptor) {
          if (isPrimitive(api.responseAdaptor)) {
            api.responseAdaptor = eval('(' + api.responseAdaptor + ')')
          }
          res = api.responseAdaptor(res)
        }
      }
      if (responseData) {
        const fields = responseData.split('.')
        fields.forEach((key) => {
          res = res[key]
        })
      }
      return Promise.resolve(res)
    })
    .catch((result) => {
      if (showErrorMsg !== false) {
        ElMessage.error(errorMsg || result.msg || result.message || '未知错误')
      }
      return Promise.reject(result)
    })
}
